import React, {useEffect, useState} from 'react';
import { Modal } from 'antd';
import axios from 'axios';

import memo from '../common/wrapMemo';

import style from './MapModel.module.scss';

let {L} = window;
const {LOCATION_URL} = window.CONFIG;

const typeMap = {
    'point': '点标注',
    'line': '线标注',
    'polygon': '面标注'
};

L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, {
    code: 'EPSG:4326',
    projection: L.Projection.LonLat,
    transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
    scale: function (zoom) {
        return 256 * Math.pow(2, zoom - 1);
    },
});

const {BASE_URL} = window.CONFIG;

// 地图对象
let drawMap = null;
// 矢量点对象
let pointLayer = null;
// 矢量线对象
let lineLayer = null;
// 矢量面对象
let polygonLayer = null;
// 定位图标
let locationMarker = null;
// 点坐标
let pointCenter = null;

const MapModel = memo((props) => {
    const {isMapModalVisible, setIsMapModelVisible, featureDetail, updateFeature, featureType, operationType} = props;

    const [type, setType] = useState('point');
    // const [jsonData, setJsonData] = useState({});           // 初始geoson数据
    const [drawGeojson, setDrawGeojson] = useState({});     // 绘制结束geojson数据
    const [isSave, setIsSave] = useState(false);
    const [tbmj, setTbmj] = useState('');

    useEffect(() => {
        initMap();
    },[]);

    // 实例化地图
    const initMap = () => {
        let map = L.map('drawMap', {
            center:[29.153607, 120.25664],
            zoom:8,
            worldCopyJump: true,
            minZoom:8,
            maxZoom:18,
            attributionControl: false,
            zoomControl: false,
            doubleClickZoom: false,
            crs: L.CRS.CustomEPSG4326
        });

        let baseLayer = L.tileLayer('https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220315000001/services/wmts/emap/default/oss?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiIxOGM1MzgxNGU5NzM0MDFkYWYzZmQyYzVjNzJkNmQ1NSIsImV4cCI6MTY2MzU3NjcyNTQwMH0.zeWetqLyiT9vzw5gypKXhUVhUyZXt4o2deMcFye9LJc&x-bg-auth-type=jwt_auth&layer=emap&style=default&tilematrixset=EPSG%3A4326&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}')
        map.addLayer(baseLayer);
        
        let layer = L.tileLayer('https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220323000008/services/wmts/emap_lab/default/oss?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiIxOGM1MzgxNGU5NzM0MDFkYWYzZmQyYzVjNzJkNmQ1NSIsImV4cCI6MTY2MzU3NjcyNTQwMH0.zeWetqLyiT9vzw5gypKXhUVhUyZXt4o2deMcFye9LJc&x-bg-auth-type=jwt_auth&layer=emap_lab&style=default&tilematrixset=EPSG%3A4326&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}');
        
        map.addLayer(layer);
        drawMap = map;
        parseFeatureData();
        
    };

    // 解析要素数据
    const parseFeatureData = () => {
        const {geojson} = featureDetail;

        if(geojson){
            const jsonData = JSON.parse(geojson);
            const type = getType(jsonData);
            setType(type);
            // setJsonData(jsonData);
            addOriginPoly(type, jsonData);
        }else{
            if(featureType === '1'){
                setType('point');
            }else{
                setType('polygon');
            }
        }
    };

    // 获取要素类型
    const getType = (geojson) => {
        if(geojson){
            const {type:jsonType} = geojson;
            const type = jsonType.toLocaleLowerCase();
            if(type.includes('point')){
                return 'point';
            }
    
            if(type.includes('line')){
                return 'line';
            }
    
            if(type.includes('polygon')){
                return 'polygon';
            }
        }
    }

    // 定位
    const location = () => {
        axios.get(LOCATION_URL).then(res => {
            if(res.status === 200) {
                const locationInfo = res?.data?.data || {};
                if(Object.keys(locationInfo.length > 0)){
                    const {lng, lat} = locationInfo;
                    addLocationMarker(lng, lat);
                }
            }
        })
    };

    // 复位
    const resetLocation  = () => {
        if(!drawMap) return;

        if(type === 'point'){
            pointCenter && drawMap.setView(pointCenter, 16);
        }

        if(type === 'polygon'){
            polygonLayer && drawMap.fitBounds(polygonLayer.getBounds());
        }   

    };

    // 添加定位图标
    const addLocationMarker = (lng, lat) => {
        console.log(lng, lat);
        if(!drawMap) return;

        if(locationMarker){
            drawMap.removeLayer(locationMarker);
            locationMarker = null;
        }
        locationMarker = L.marker([lat,lng], {
            icon: L.icon({
                iconUrl: `${BASE_URL}/images/marker.png`,
                iconSize: [26, 26],
                iconAnchor: [12, 12],
            })
        }).addTo(drawMap);
        // 定位
        drawMap.setView([lat, lng], 16);
    }

    const addOriginPoly = (type, jsonData) => {
        if(type === 'point'){
            addMarker(jsonData);
        }

        if(type === 'polygon'){
            addPolygon(jsonData);
        }
    };

    // 保存
    const save = () => {
        if(isSave){
            const {uid} = featureDetail;
            let {geometry= {}} = drawGeojson;

            let items = { geojson: JSON.stringify(geometry) };
            
            if(type === 'polygon'){
                items['tbmj'] = tbmj;
            }
            const params = {
                operationContent:{
                    items: items,
                    itemsPrev:{},
                    operation: 'update',
                    uid
                }
            };
            updateFeature(params);
        }
    };

    // 返回
    const back = () => {
        setIsMapModelVisible(false);
    };

    // 绘制
    const draw = (type) => {
        if(type === 'point'){
            drawPoint();
        }

        if(type === 'line'){
            drawLine();
        }

        if(type === 'polygon'){
            drawPolygon();
        }
    };

    // 添加点
    const addMarker = (jsonData) => {
        const {coordinates} = jsonData;
        
        let center = L.latLng(coordinates[1], coordinates[0]);
        pointCenter = center;
        pointLayer = L.marker([coordinates[1],coordinates[0]], {
            icon: L.icon({
                iconUrl: `${BASE_URL}/images/marker.png`,
                iconSize: [26, 26],
                iconAnchor: [12, 12],
            })
        }).addTo(drawMap);
        drawMap.setView(center, 16);
    };

    // 添加面
    const addPolygon = (jsonData) => {
        polygonLayer = L.geoJSON(jsonData,{color: "red", weight: 1}).addTo(drawMap);
        drawMap.fitBounds(polygonLayer.getBounds());
    };

    // 绘制点
    const drawPoint = () => {
        clear();

        function pointClick (e) {
            const {latlng: {lat, lng}} = e;
            // pointLayer = L.circle(e.latlng,{radius:100,color:'red',fillColor:'red',fillOpacity:1}).addTo(drawMap);
            pointLayer = L.marker([lat,lng], {
                icon: L.icon({
                    iconUrl: `${BASE_URL}/images/marker.png`,
                    iconSize: [26, 26],
                    iconAnchor: [12, 12],
                })
            }).addTo(drawMap);
            setDrawGeojson(pointLayer.toGeoJSON());
            setIsSave(true);
            drawMap.off('click',pointClick);
        }

        drawMap.on('click', pointClick);
    };

    // 绘制线
    const drawLine = () => {
        clear();

        let points=[];
        let lines = new L.polyline(points);
        let tempLines = new L.polyline([]);
        drawMap.on('click', onClick);    
        drawMap.on('dblclick', onDoubleClick);
 
        function onClick(e) {
            points.push([e.latlng.lat,e.latlng.lng]);
            lines.addLatLng(e.latlng);
            drawMap.addLayer(lines);
            drawMap.on('mousemove',onMove);  
        }

        function onMove(e) {
            if(points.length>0) {
                const ls = [points[points.length-1],[e.latlng.lat,e.latlng.lng]];
                tempLines.setLatLngs(ls);
                drawMap.addLayer(tempLines);
            }
        }
 
        function onDoubleClick(){
            lineLayer = L.polyline(points);
            drawMap.addLayer(lineLayer);
            setDrawGeojson(pointLayer.toGeoJSON());
            points=[]; 
            lines && drawMap.removeLayer(lines);
            tempLines && drawMap.removeLayer(tempLines);
            drawMap.off('mousemove', onMove);
            drawMap.off('click', onClick);
            drawMap.off('dblclick', onDoubleClick);
        }
    };

    // 绘制面
    const drawPolygon = () => {
        clear();
        let drawPolygonPoints = []; 
        drawMap.doubleClickZoom.disable();
        let line1 = new L.polyline([],{color: "#ff7800", weight: 1});
        let line2 = new L.polyline([],{color: "#ff7800", weight: 1});
        let points = [];
        drawMap.on('click', onClick);                  
        drawMap.on('dblclick', onDoubleClick);
        drawMap.on('mousemove', onMove);               
        
        function onClick(e) {
            points.push([e.latlng.lat, e.latlng.lng]);
            line1.addLatLng(e.latlng);
            drawMap.addLayer(line2);
            drawMap.addLayer(line1);
            drawPolygonPoints.push(e.latlng);
        }
        function onMove(e) {
            if (points.length > 0) {
                let ls = [points[points.length - 1], [e.latlng.lat, e.latlng.lng], points[0]];
                line2.setLatLngs(ls);
            }
        }
        function onDoubleClick(e) {
            polygonLayer = L.polygon(points,{color: "#ff7800", weight: 1}).addTo(drawMap);
            setDrawGeojson(polygonLayer.toGeoJSON());

            let tempPoints = [];
            for (var i = 0; i < drawPolygonPoints.length; i++) {
                tempPoints.push(drawPolygonPoints[i]);
            }
            tempPoints.push(e.latlng);

            // 计算面积
            let distance = calcArea(tempPoints);
            // 平方公里转换为亩
            let tbmj = ((distance / 1000000) * 1500).toFixed(2);
            setTbmj(tbmj);
            points = [];
            if(line1){
                drawMap.removeLayer(line1);
                line1 = null;
            }
            if(line2){
                drawMap.removeLayer(line2);
                line2 = null;
            }
            drawMap.off('click', onClick);                      //点击地图
            drawMap.off('dblclick', onDoubleClick);
            drawMap.off('mousemove', onMove);                   //双击地图
            drawMap.doubleClickZoom.enable();
            setIsSave(true);
        }

        //计算面积
        function calcArea(latLngs) {
            var pointsCount = latLngs.length,
                area = 0.0,
                d2r = Math.PI / 180,
                p1, p2;
            if (pointsCount > 2) {
                for (var i = 0; i < pointsCount; i++) {
                    p1 = latLngs[i];
                    p2 = latLngs[(i + 1) % pointsCount];
                    area += ((p2.lng - p1.lng) * d2r) *
                        (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
                }
                area = area * 6378137.0 * 6378137.0 / 2.0;
            }
            return Math.abs(area);
        }
    };

    // 清空绘制图形
    const clear = () => {
        if(!drawMap) return;

        if(pointLayer){
            drawMap.removeLayer(pointLayer);
            pointLayer = null;
        }

        if(lineLayer){
            drawMap.removeLayer(lineLayer);
            lineLayer = null;
        }

        if(polygonLayer){
            drawMap.removeLayer(polygonLayer);
            polygonLayer = null;
        }
    };

    return (
        <>
            <Modal 
                footer={null} 
                width={window.innerWidth - 80}
                bodyStyle={{padding: 0}}
                visible={isMapModalVisible} 
                closable={false}>
                    <div id='drawMap' className={style.drawMap}></div>
                    {
                        operationType === 'edit' &&
                        <>
                            <div className={style.drawlabel} onClick={() => draw(type)}>{typeMap[type]}</div>
                            <div className={style.location} onClick={location}>IP 定位</div>
                            <div className={style.resetLocation} onClick={resetLocation}>复位</div>
                        </>
                    }
                    
                    <div className={style.drawBtns}>
                        {
                            operationType === 'edit' &&
                            <span className={style.save} onClick={save}>保存</span>
                        }
                        <span className={style.back} onClick={back}>返回</span>
                    </div>
            </Modal>
        </>
    )
});

export default MapModel;